let baogeUtils = require("slib/baogeUtils")
let pageUtils = require("slib/pageNode")

// 单例模式 只需要实例化一次
function BaogeBase(){
    this.selectorConfig = {
        modelClose: "com.smile.gifmaker:id/close", // 可能会弹出青少年模式
        modelISee: "com.smile.gifmaker:id/positive", // 可能会弹出青少年模式
    }
}
// 原型属性
BaogeBase.prototype.timeOut = 0; // 查找节点失败时等待的毫秒数
BaogeBase.prototype.ecVersion = ''; // 当前EC版本
// 初始化启动自动化环境
BaogeBase.prototype.init = function (options) {
    if (baogeUtils.getType(options) === "Object") {
        let tempTime = random(+options.restTimeMin, +options.restTimeMax);
        // logd("随机休息时间为:" + tempTime + "分钟");

        this.globaMinDelay = options.globalDelay.min; // 全局最小延时
        this.globaMaxDelay = options.globalDelay.max; // 全局最大延时

        this.fixedTimeHours = options.fixedTimeHours; // 定时启动小时
        this.fixedTimeMinutes = options.fixedTimeMinutes; // 定时启动分钟

        this.limitEpisodes = options.limitEpisodes; // 限制集数
        this.runTime = options.runTime * 60 * 1000; // 运行时长 把分钟变成秒
        this.restTime = tempTime * 60; // 休息时长
        this.workIndex = +options.workIndex; // 作品的索引
        this.ksId = options.ksIds; // 快手ID号
        this.ksUserName = options.ksUserName.trim(); // 快手ID号
        this.mode = +options.mode; // 当前模式
        this.fixedTime = +options.fixedTime; // 脚本启动时间 小时
        this.fastVideoIsChecked = options.fastVideoIsChecked; // 是否开启快进视频
        this.fastVideoTime = options.fastVideoTime || 4; // 快进视频方式 注: 次数 快进一次!
        this.isEndStop = options.isEndStop; // 是否开启快进视频
        this.videoTabs = options.videoTabs || []; // 存放用户作品与集数数据
        updateConfig('videoData', JSON.stringify(this.videoTabs))

        // logd('this.isEndStop', this.isEndStop);
        /*for (const key in options) {
            logd(key + ":" + options[key]);
        }*/
        /*logd('全局最小延时:' + this.globaMinDelay);
        logd('全局最大延时:' + this.globaMaxDelay);
        logd('限制集数:' + this.limitEpisodes);
        logd('运行时长:' + this.runTime + "秒");
        logd('本次休息时长:' + this.restTime + "秒");*/
        // logd('workIndex:' + this.workIndex); // 3
        /*logd('ksId:' + this.ksId);
        logd('ksUserName:' + this.ksUserName);
        logd('mode:' + this.mode);
        logd('本软件将在:' + this.fixedTime);
        logd('是否开启快进视频:' + this.fastVideoIsChecked);*/

        /*this.videoTabs.forEach((item) => {
            baogeUtils.logStringify(item)
        })*/
        // logd("读取到上次作品数量:" + this.videoTabs.length)
        // logd("this.fastVideoTime:" + this.fastVideoTime)

    } else {toast('请传对象类型'); }

    const version = baogeUtils.getECversion(); // 获取当前ec版本号
    this.ecVersion = version; // 挂载到本对象中方便后面有地方需要用

    // 比较当前版本满足返回true
    const versionCompare = () => {
        return version[0] > 6 || (version[0] === 6 && version[1] >= 7)
    }
    for (let i = 0; i < 3; i++) {
        logi("第" + (i + 1) + "次启动自动化服务结果: " + startEnv()); // 启动自动化环境

        if (isServiceOk()) { // 检测自动化服务是否正常

            if (versionCompare()) {daemonEnv(true);}

            // 初始化获取一次后面可以方便使用 无需频繁调用
            this.screenHeight = device.getScreenHeight();
            this.screenWidht = device.getScreenWidth();
            // toast("当前设备宽:" + this.screenWidht + ', 高:' + this.screenHeight)
            return true;
        }
    }
    toast("自动化服务启动失败，无法执行脚本");
    // loge("自动化服务启动失败，无法执行脚本");
    exit();
}

// 全局延时共用方法
BaogeBase.prototype.globalDelay = function () {
    sleep(this.globaMinDelay, this.globaMaxDelay);
}

/*
* 进入到短剧页面
*
* */
/*BaogeBase.prototype.enterShortVideo = function () {
    const nodeInfo = baogeUtils.getNode(text('分享').id('com.smile.gifmaker:id/forward_count'))
    // baogeUtils.logStringify(nodeInfo);

    if(nodeInfo) {
        const sNode = baogeUtils.getNode(text('短剧').id('com.smile.gifmaker:id/plc_tv_biz_text'));
        sNode && sNode.click();
        this.globalDelay()
        return true;
    }
    return false;
}*/
// 采集用户的作品数据
BaogeBase.prototype.worksDataSave = function () {
    let count = this.workNum;
    let flag = true;
    if (!this.workNum) {
        // toast('未知作品数量');
        baogeUtils.backs();
        return false;
    }

    let num = 0; // 记录已存在的作品超过2个就不采集
    while (flag) {
        sleep(1000);
        pageUtils.adolescentMode(); // 以防青少年模式弹窗

        let name = pageUtils.videoName(count); // 获取当前剧名
        // logd("name:" + name + ", count:" + count);
        if (!name) {
            // logd('获取剧名失败');
            continue
        } // 如果获取剧名失败那么就跳过

        let timeName = pageUtils.videoTime(); // 获取当前剧发布时间
        // logd("timeName:" + timeName);

        if (!timeName) { // 如果获取发布时间失败那么就跳过
            // logd('获取作品发布时间失败!!!');
            continue;
        }

        let currentVideoInfo = baogeUtils.findTabByName(this.videoTabs, timeName);
        // baogeUtils.logStringify(currentVideoInfo);

        if (currentVideoInfo) {
            // logd('获取发布时间 -> 存在');
            this.swiperPrevPage();
            sleep(1000);
            continue
        }
        
        if (timeName && !currentVideoInfo) {
            this.videoTabs.unshift({id: count, videoName: name, index: count, gather: 0, videoTime: timeName});
            toast('采集作品信息中第(' + (this.workNum - count + 1) + ")个 总共数量:" + (this.workNum) + "个");
            count--;
            this.swiperPrevPage();
        }
        // logd(this.videoTabs.length);
        // logd(this.workNum);

        if (this.videoTabs.length >= this.workNum || count < 0) {
            // logd('采集退出');
            break
        }

    }

    baogeUtils.saveConfigJsonFile(this.videoTabs)
    updateConfig('videoData', JSON.stringify(this.videoTabs))
    toast('采集用户作品并保存完成');
    this.globalDelay();
    baogeUtils.backs();
}

/*
* 跳转到指定页面 
* index: 根据索引来操作  // 0: 首页 1: 精选 2: 消息 3: 我  注: 后面可能会添加更多
* */
BaogeBase.prototype.targetPage = function (callback) {
    removeNodeFlag(0) // 强制刷新页面

    if (pageUtils.mePage(this)) {callback && callback('me'); return true}

    if (pageUtils.workPage(this)) {callback && callback('work'); return true}

    if (pageUtils.homePage(this)) {callback && callback('home'); return true}

    if (pageUtils.videoName(this)) {callback && callback('video'); return true}

    // if (pageUtils.workShortPage(this)) { callback && callback('short'); return true }

    if (pageUtils.selectionPage(this)) {callback && callback('selection'); return true}

    if (pageUtils.msgPage(this)) {callback && callback('msg'); return true}

    // logd('退回');
    back();
    this.globalDelay();
}

// 挂载个外面直接获取设备信息方法
BaogeBase.prototype.getDeviceInfo = function () {
    return {
        screenHeight: this.ScreenHeight,
        screenWidht: this.ScreenWidht
    }
}

// 往上翻 ->视频
BaogeBase.prototype.swiperPrevPage = function () {
    const x = this.screenWidht / 2 + random(1, 10);
    const y = this.screenHeight / 2  + (this.screenHeight / 2 / 2) + random(20, 50);
    const endX = x + random(10, 30);
    const endY = 20 + random(1, 10);
    return baogeUtils.randomSwiper(x,y,endX,endY);
}

// 往下翻
BaogeBase.prototype.swiperNextPage = function () {
    const x = this.screenWidht / 2 + random(1, 10);
    const y = this.screenHeight / 2  - (this.screenHeight / 2 / 2);
    const endX = x + random(1, 4);
    const endY = this.screenHeight / 2 + this.screenHeight / 2 / 2;
    return baogeUtils.randomSwiper(x,y,endX,endY)
}

// 快进视频
BaogeBase.prototype.fastForwardVideo = function (isDelay) {
    const countRandom = 1;
    for (let i = 0; i < countRandom; i++) {
        const smallRandom = random(5, 15);
        const x = this.screenWidht / 2 / 2 + smallRandom; // 屏幕宽度的一半的一半
        const y = this.screenHeight / 2 + smallRandom; // 设置高度的一半
        const endX = x + random(50, 80); // 拖动视频的结束坐标
        const endY = this.screenHeight / 2  + smallRandom;
        baogeUtils.randomSwiper(x,y,endX,endY)
        isDelay && this.globalDelay()
    }
}

BaogeBase.prototype.wordEndSave = function (){
    // 你已看完全部作品!
    toast('作品数量已经全部观看完成!');
    // logd('作品数量已经全部观看完成!');
    updateConfig('workIndex', 1) // 重置作品索引
    this.workIndex = 1;
    if (this.isEndStop) {
        exit()
    }
    baogeUtils.backs();
}

// 在作品列表视频中 找用户指定作品位置
BaogeBase.prototype.findVideoIndex = function () {
    let flag = true;
    let item = baogeUtils.findTabByIndex(this.videoTabs, this.videoTabs.length - this.workIndex + 1);
    // baogeUtils.logStringify(item)

    if (!item && this.workIndex >= this.workNum) { // 全部看完
        this.wordEndSave();
        return
    }
    this.currentWork = item; // 得到当前的正在刷视频的信息
    let timeName = ''
    let currentItem = {}
    let currentName = '';
    let faild = 0;
    while (flag) {
        pageUtils.adolescentMode(); // 以防青少年模式弹窗
        timeName = pageUtils.videoTime(); // 获取作品发布时间
        if (currentName !== timeName && timeName) {
            currentName = timeName;
        } else {
            faild++;
            // logd("同名"+ faild +"次, 超过5次back一下");
            if (faild > 5) {
                baogeUtils.backs();
                break;
            }
        }

        if (timeName) {
            currntItem = baogeUtils.findTabByName(this.videoTabs, timeName);
            // baogeUtils.logStringify(currntItem);

            if (currntItem && currntItem.index > item.index) {
                // 往上滑
                this.swiperPrevPage();
            } else if(currntItem && currntItem.index < item.index) {
                // 往下滑
                this.swiperNextPage();
            } else if(currntItem && currntItem.index === item.index) {
                return true;
            } else {
                // logd('跳出匹配剧名');
                break;
            }

            if (currntItem && !baogeUtils.isEmptyObject(currntItem)) {
                toast("当前需要播放的作品是第:[" + (this.videoTabs.length - currntItem.index + 1) +"]个")
            }
        }
        // logd('正在匹配剧名中.....');
        sleep(2000);
    }
}

/*
* 默认查找4次 如果4次未找到返回false 如果找到返回 数据中最后一个元素节点
* isclick默认为false
* */
BaogeBase.prototype.nextNode = function (dataNodes, count) {
    count = count || 4; // 默认查找次数
    if (!Array.isArray(dataNodes)) {
        // logd("请传入节点数组")
        return false
    }
    let res = null;

    for (let i = 0; i < count; i++) {
        let arrs = []; // 装每次返回值
        for (let j = 0; j < dataNodes.length; j++) {
            res = this.addForNode(dataNodes[j])
            arrs.push(res)
            if (!res) sleep(50)
        }
        if (arrs[arrs.length - 1]) break; // 如果确认最后一个数组元素是true 就跳出
        sleep(50)
    }
    return res
}

BaogeBase.prototype.addForNode = function (nodeInfo) {
    let currnetNode = baogeUtils.getNode(nodeInfo.selector);
    if (currnetNode && nodeInfo.isClick) {
        currnetNode.click()
        this.globalDelay()
    }
    return currnetNode;
}
// ------------------------------原型方法Start------------------------------

/*
* keyWord: 需要搜索的关键词
* delay: 延时
* return: true通过快手ID进入搜索页面成功, false进入失败
* */
BaogeBase.prototype.enterSearchPage = function () {
    let res = this.nextNode([
        {selector: id(this.selectorConfig.modelClose), isClick: true},
        {selector: id('com.smile.gifmaker:id/search_btn'), isClick: true},
        {selector: id(this.selectorConfig.modelISee), isClick: true},
        {selector: text('搜索').id('com.smile.gifmaker:id/right_tv'), isClick: false}
    ],6)

    if (!res) {
        // logd("进入搜索页面失败");
        return false
    }

    let nodeInfo = baogeUtils.getNode(id("com.smile.gifmaker:id/editor")); // 输入框节点

    if (nodeInfo) {
        // nodeInfo.clearText(); // 清空一下输入框
        if (!this.ksId) { toast('快手ID号为空'); return false }
        if (nodeInfo.inputText(this.ksId)) { // 给输入框添加内容
            this.globalDelay()
            baogeUtils.getNode(id('com.smile.gifmaker:id/right_tv')).click()
            // toast('进入搜索页面成功');
            this.globalDelay()
            return true
        }
    }
    return false
}

/*
* ksId: 当前快手ID号
* delay: 延时
* return: true进入到搜索到作品人的ID个人中心页面, false进入失败
* */
BaogeBase.prototype.handleClickUserAvatar = function () {
    /*let randomNum = random(10,20)
    const nodeInfo = this.getNode(textMatch(".*" + ksId + "$").id("com.smile.gifmaker:id/text1"));
    if (nodeInfo) {
        let isRes = clickPoint(nodeInfo.bounds.left + randomNum, nodeInfo.bounds.top);
        sleep(random(1000,3000));
        return isRes;
    }*/

    // 选择中最外层父子节点
    const nodeInfo = baogeUtils.getNode(id("com.smile.gifmaker:id/recycler_view")
        .child()
        .clz('android.view.ViewGroup'),true)
    // baogeUtils.logStringify(nodeInfo.nextSiblings())

    if (nodeInfo) {
        let isRes = false;
        const sNode = nodeInfo.nextSiblings();
        // baogeUtils.logStringify("sNode" + sNode)
        // 得到搜索到的用户头像图片节点信息
        if (sNode && sNode.length > 0 && sNode[0].bounds.top > 200) {
            isRes = clickPoint(57 + random(5, 10), sNode[0].bounds.top + random(10, 15))
            // baogeUtils.showToast('点击用户即将进入用户个人中心!');
        }
        this.globalDelay()
        return isRes;
    }

    return false;
}

// 进入个人作品页面
BaogeBase.prototype.works = function (){

    if (this.workIndex < 0) {
        // toast('用户作品索引范围出错:' + this.workIndex);
        return false
    }

    const workNode = baogeUtils.getNode(textMatch('.*作品.*').clz("android.widget.TextView")); // 获取到所有作品数量选项
    if (!workNode) {
        // toast('未找到用户作品页面节点');
        return false
    }

    // 由于有时作品刷新不是最新的 所以需要刷新一下
    let workNum = baogeUtils.matchNumber(workNode.text); // 正则匹配当前用户作品数量
    toast('识别到当前用户作品数量:' + workNum + "个");

    if (workNum <= 0) {
        toast('该作者未发布作品, 请换一下!!!');
        return false
    }

    this.workNum = workNum; // 添加到当前对象身上方便后面判断用

    if (this.workIndex >= workNum) {
        this.wordEndSave();
        return
    }
    this.globalDelay()
    const nodeInfo = baogeUtils.getNode(index('0').id('com.smile.gifmaker:id/player_cover'));
    return nodeInfo && nodeInfo.click();
}

// 刷视频中
// interval: 隔几秒快进一次
BaogeBase.prototype.brushVideoing = function () {
    if (pageUtils.checkIsSeeVideoPage()) { // 检测是否在视频播放页面
        /**
         * 1. 检测是否有充值页面弹出 如果有
         * 2. 那么循环3次找一下有没有免费视频观看
         * 3. 如果没有找到免费视频观看 说明此剧的广告收益已没有!那么就退出
         * */
        if (pageUtils.kbRecharge(this.screenHeight) && !pageUtils.feeEpisode()) {
            if (!pageUtils.continueView()) {  // 退出之前 还要确保是不是弹出了继续观看
                // toast('发现没有广告了, 还看毛啊!');
                return false
            }
        }

        // 查看一下当前这个视频是否已看到最顶集
        let allGather = pageUtils.updateGather();
        if (allGather && allGather <= this.currentWork.gather) {
            // toast('嘿嘿!当前视频已看完全集!');
            // 重置一下
            baogeUtils.updateGatherByName(this.videoTabs, this.currentWork.videoName, 0);
            // 保存用户的信息
            baogeUtils.saveConfigJsonFile(this.videoTabs);
            return false;
        }

        let episodesNum = baogeUtils.matchNumber(pageUtils.episodes()); // 匹配集数
        if (episodesNum > 0) {
            toast("当前正在播放[" + episodesNum + "]集 总共" + allGather + "集");

            if (this.currentWork.gather - episodesNum > 10) { // 这里说明需要选集
                // logd('需要选集');
                if (pageUtils.selectGather(true) && this.clickGatherTabs(this.currentWork.gather)) {
                    // 如果选项卡选择成功 -> 开始滑动 开始找集数匹配
                    this.findGather();
                    // logd('....');
                }
            } else {
                // 获取到的界面集数要比上次保存的集数数值大才进行保存
                if (episodesNum > this.currentWork.gather) {
                    // logd('更新集数,方便下次使用');
                    baogeUtils.updateGatherByName(this.videoTabs, this.currentWork.videoName, episodesNum);
                }
                
                // 保存用户的信息
                baogeUtils.saveConfigJsonFile(this.videoTabs);
                // logd(this.videoTabs);
            }
        }
        sleep(1000);
        let currentDelay = random(10,30);
        toast('本次观看视频等待:' + (currentDelay) + "秒!");

        // 检测以防意外弹出 微信或者支付宝 充值界面
        pageUtils.paymentAlert();

        // 实现倒计时效果 这里这样写有点傻 后面想办法优化一下吧
        for (let i = 0; i < currentDelay; i++) {
            if (!pageUtils.checkIsSeeVideoPage()) {
                // toast('未识别到当前在刷视频广告中');
                break
            }

            if(i % 2 === 0 && pageUtils.kbRecharge(this.screenHeight) && pageUtils.feeEpisode()) {
                // toast('提前退出');
                break
            }

            this.fastVideoIsChecked && i % this.fastVideoTime === 0 && this.fastForwardVideo()
            toast("倒计时剩余时间:" + (currentDelay - i) + "秒");
            sleep(1000);
        }

        pageUtils.feeEpisode(); // 免费看广告中
        // 保存用户的信息
        baogeUtils.saveConfigJsonFile(this.videoTabs);

        // --------后期请删除此段代码------
        /*let item = baogeUtils.findTabByIndex(this.videoTabs, this.videoTabs.length - this.workIndex + 1);
        baogeUtils.logStringify(item)*/
        // --------后期请删除此段代码------

        // 上滑
        this.swiperPrevPage();
    }
    return true;
}

// 点击选集上面的集数选项卡
BaogeBase.prototype.clickGatherTabs = function (gather) {
    let cNode = '';
    let pNode = pageUtils.getAllGatherParent();
    if (pNode) { // 获取到所有集数选项卡
        removeNodeFlag(0);
        cNode = pNode.allChildren();
    }
    if (cNode && cNode.length) {
        // logd('选中集数列表选项卡')
        for (let i = 0; i < cNode.length; i++) {
            let endGather = cNode[i].text && cNode[i].text.split('-')[1]; // 取出格式如 1-30 31-60
            if (endGather >= gather) { // 选中选项卡
                // logd('选中成功');
                cNode[i].click();
                sleep(3000);
                return true;
            }
        }
    }
    return false
}

// 找历史观看纪录集数
BaogeBase.prototype.findGather = function () {
    let flag = true;
    let j = 0;
    while (j <= 15 && flag){
        j++;
        // toast('正在找带锁的集数');
        removeNodeFlag(0)
        let nodeInfo = pageUtils.getAllGatherParent();
        if (!nodeInfo) { continue }
        let pNode = nodeInfo.parent();
        if (!pNode) { continue }
        let sNode = pNode.nextSiblings(); // 所有选集的框
        if (!sNode) { continue }
        let pTop = sNode[0].bounds.top;
        let pBottom = sNode[0].bounds.bottom;
        let pRight = sNode[0].bounds.right;
        let aNode = sNode[0].allChildren();
        if (!aNode) { continue }
        for (let i = 0; i < aNode.length; i++) {
            if (aNode[i].bounds.top >= pTop && aNode[i].bounds.bottom < pBottom) {
                let currentView = aNode[i].child(0).allChildren(); // 可视范围内的一个视频
                if (currentView && currentView.length >= 3) { // 获取它的所有子节点
                    // toast('找到带锁的了!');
                    let isClick = aNode[i].click();
                    flag = false;
                    break;
                }
            }
        }
        sleep(1000);
        pTop && baogeUtils.randomSwiper(pRight / 2,(pTop + pBottom) / 2,pRight / 2 ,pTop, 1500)
    }
}

// ------------------------------原型方法End--------------------------

// 以闭包的形式创建一个引用自动变量的构造器
const Baoge = (function (){
    let instance = null; // 默认第一次为null

    // 闭包实现过程
    return function (name) {
        if (!instance) instance = new BaogeBase(name); // 如果不存在 就new个实例对象出来
        return instance; // 如果当前实例对象已经存在 直接返回当前实例对象
    }
})();

module.exports = new Baoge();


